
#include	"Weapon.h"
#include	"Ship.h"
#include	"defs.h"
#include	"SpaceShooter.h"
#include	"Util.h"

Weapon::Weapon(){
	projectilesSurface = NULL;
	pShip = NULL;
	isFiring = false;
	firingInterval = 0;
	enemyWeapon = false;
}

bool Weapon::init(weaponTypes w, Ship* pShip){

	if(pShip == NULL)
		return false;

	this->pShip = pShip;

	weaponType = w;

	if(enemyWeapon)
		p.invertFireDirection();

	if((projectilesSurface = Surface::OnLoad("images/projectiles.png")) == NULL)
		return false;

	switch(weaponType)
	{
		case PULSE_GUN:

			if(!p.init(Projectile::PULSE, projectilesSurface))
				return false;

			weaponFireRate = PULSE_GUN_RATE;

		break;

		case LASER_GUN:

			if(!p.init(Projectile::LASER, projectilesSurface))
				return false;

			weaponFireRate = LASER_GUN_RATE;

		break;

		case TRIPLE_PULSE_GUN:

			if(!p.init(Projectile::PULSE, projectilesSurface))
				return false;

			weaponFireRate = TRIPLE_PULSE_RATE;

		break;

		default:
			return false;
	}

	return true;
}

void Weapon::cleanup(){
	
	projectiles.clear();

	if(projectilesSurface)
		SDL_FreeSurface(projectilesSurface);
	
	projectilesSurface = NULL;
}

void Weapon::fire(){

	if( pShip->getY() < -5 )
		return;

	if(SDL_GetTicks() < firingInterval)
		return;
	else
		firingInterval = SDL_GetTicks() + weaponFireRate;
	
	switch(weaponType)
	{
		case PULSE_GUN:

			if(!enemyWeapon)
				p.setPos( pShip->getX() + 23 , pShip->getY() );
			else
				p.setPos( pShip->getX() + 23, pShip->getY() + 40 );

			p.setSpeedX(0);
			p.setSpeedY(12.0f);

			projectiles.push_back(p);

		break;

		case LASER_GUN:

			if(!enemyWeapon)
				p.setPos( pShip->getX() + 23 , pShip->getY() );
			else
				p.setPos( pShip->getX() + 23, pShip->getY() + 40 );

			p.setSpeedX(0);
			p.setSpeedY(12.0f);

			projectiles.push_back(p);

		break;

		case TRIPLE_PULSE_GUN:

			p.setPos( pShip->getX() + 23 , pShip->getY() );

			//left
			p.setSpeedX(-1.0f);
			p.setSpeedY(12.0f);

			projectiles.push_back(p);

			//center
			p.setSpeedX(0);
			p.setSpeedY(12.0f);

			projectiles.push_back(p);

			//right
			p.setSpeedX(1.0f);
			p.setSpeedY(12.0f);

			projectiles.push_back(p);

		break;
	}
}

void Weapon::loopProjectiles(){

	if(isFiring)
		fire();

	std::list<Projectile>::iterator it;
	std::vector<std::list<Projectile>::iterator> elementsToErase;
	std::list<Object*>::iterator oIt;
	
	Ship* playerShip = SpaceShooter::pGame->getPlayerShip();

	for(it = projectiles.begin(); it != projectiles.end(); it++)
	{
		it->loop();

		//deletar projetil se fora da tela ou ja deu dano
		if( it->getX() < 0 || it->getX() > WND_WIDTH ||
			it->getY() < 0 || it->getY() > WND_HEIGHT || it->madeDamage)
				elementsToErase.push_back(it);
		else
		{
			SDL_Rect projRect;
			SDL_Rect shipRect;
			
			projRect = it->getColRect();

			if(enemyWeapon)
			{
				//check collision
				shipRect = playerShip->getColRect();

				if( Util::rectCollided(projRect, shipRect) )
				{
					playerShip->takeShot(it->projectileType);
					it->madeDamage = true;
				}
					
			}
			else
			{
				//Check all objects for collisions
				for(oIt = SpaceShooter::objectList.begin(); oIt != SpaceShooter::objectList.end(); oIt++)
				{
					shipRect = ((Ship*) *oIt)->getColRect();

					if( Util::rectCollided(projRect, shipRect) )
					{
						((Ship*) *oIt)->takeShot(it->projectileType);
						it->madeDamage = true;
					}
				}
			}
			
		}		
	}

	for(unsigned int i=0; i< elementsToErase.size(); i++)
		projectiles.erase(elementsToErase[i]);

	elementsToErase.clear();
}

void Weapon::renderProjectiles(SDL_Surface* destSurface){
	
	std::list<Projectile>::iterator it;

	for(it = projectiles.begin(); it != projectiles.end(); it++)
		it->render(destSurface);
}

void Weapon::setEnemyWeapon(bool ew){
	enemyWeapon = ew;
}

void Weapon::setFireRate(int fr){
	if(fr > 0)
		weaponFireRate = fr;
}

void Weapon::setShip(Ship* pS){
	if(pS != NULL)
		pShip = pS;
}

Projectile* Weapon::getProjectile(){
	return &p;
}
